export default class TaskFly {
  constructor(viewer,arr) {
    this.viewer = viewer

    //时间间隔（S）  指两个点所需要的时间
    this.interval = 5
  
    this.index = 0 //差值经纬度索引
    this.maxIndex = 0 //最大差值经纬度数组索引
    this.pathIndex = 0//当前经纬度数组索引
    this.forNum = 20 //差值间隔
    this.isLookAt = true //锁定视角
    this.autoDirection = true //自动调整方向
    this.lineNumner = [] //存路线数组
    this.Primitive = null
    this.entityPath = null
    this.hpRoll = new Cesium.HeadingPitchRoll()
    this.linePath = []  //Cesium.Cartesian3
    this.showPath = []  //Cesium.Cartesian3

    this.timer = null


    this.fixedFrameTransform = Cesium.Transforms.eastNorthUpToFixedFrame;
    this.start(arr)
  }
  
  //轨迹开始
  /*
   * arr是轨迹点集合
   */
  
   start = (arr) =>{
    if(arr.length === 0) return
    this.showPath = []
    //插入坐标
    arr.forEach((item,index)=>{
      if(index >0){
        this.showPath = this.showPath.concat(this.getPosition( Cesium.Cartesian3.fromDegrees(arr[index-1][0],arr[index-1][1],arr[index-1][2]) , Cesium.Cartesian3.fromDegrees(item[0],item[1],item[2]) , this.interval,2))
      }
    })
    //初始化视角
    // this.viewer.camera.setView({
    //   destination: Cesium.Cartesian3.fromDegrees(arr[0][0], arr[0][1], arr[0][2] + 1200), //设置位置
    //   orientation: {
    //       heading: Cesium.Math.toRadians(0),
    //       pitch: Cesium.Math.toRadians(-90),
    //       roll: 0
    //   }
    // });

    this.viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(113.12439212640695,27.851237153461124,243.90717842319685), //设置位置
      orientation: {
          heading: Cesium.Math.toRadians(357.0137118149973),
          pitch: Cesium.Math.toRadians(-29.320680270726676),
          roll: 0
      }
    });

  
    this.index = 1
    this.maxIndex = this.showPath.length - 1 
    this.initModel()
    this.timer = setInterval(() => {
      this.render()
    }, 20);
    // this.viewer.scene.preUpdate.addEventListener(this.render)
  }


  update = (arr) => {
    //更新坐标插入
    arr.forEach((item,index) => {
      if(index > 0){
        this.showPath =  this.showPath.concat(this.getPosition( Cesium.Cartesian3.fromDegrees(arr[index-1][0],arr[index-1][1],arr[index-1][2]) , Cesium.Cartesian3.fromDegrees(item[0],item[1],item[2]) , this.interval,2))
        this.maxIndex = this.showPath.length-1
      }
    })
  }

  //稀释轨迹点
  getPosition = (startP, endP, duration,speed =1) => {
    let arr = []
    // 这里是ms  1000是1S  speed来控制速度大小
    duration = duration * 1000/ speed
    for (let i = 0; i <= duration; i = i + this.forNum) {
        let pos = Cesium.Cartesian3.lerp(startP, endP, i / duration, new Cesium.Cartesian3());
        arr.push(pos)
    }
    if (duration % this.forNum !== 0) {
        arr.push(endP)
    }
    return arr
  }

  render = () =>{
    //大于的时候 行程走完了
    if(this.index > this.maxIndex){
      this.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)

      return
    }
    if(this.autoDirection){
      const heading = this.getHeading(
        this.showPath[this.index -1],
        this.showPath[this.index]
      )
      if (heading) this.hpRoll.heading = heading

      this.linePath.push(this.showPath[this.index])
      Cesium.Transforms.headingPitchRollToFixedFrame(
        this.showPath[this.index],
        {
          heading: Cesium.Math.toRadians(90),
          pitch: 0,
          roll: 0
        },
        // this.hpRoll,
        Cesium.Ellipsoid.WGS84,
        this.fixedFrameTransform ,
        this.Primitive.modelMatrix
      )
      // if (this.isLookAt){
      //   this.viewer.camera.lookAt(this.showPath[this.index], new Cesium.HeadingPitchRange(this.hpRoll.heading, -45, 300))
      // }
      this.index += 1
    }
  }

  //加载模型
  initModel = () =>{
    let pos = this.showPath[0]
    this.linePath = [pos]
    this.Primitive = this.viewer.scene.primitives.add( //加载模型
      Cesium.Model.fromGltf({
          // url: 'data/wurenji1c.glb',
          url: 'data/model/model-walk/walk.gltf',
          modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
              pos,
              {
                heading: Cesium.Math.toRadians(90),
                pitch: 0,
                roll: 0
              },
              Cesium.Ellipsoid.WGS84,
              this.fixedFrameTransform,
          ),
          scale: 5,
      })
    )

    this.entityPath = this.viewer.entities.add({ 
      position: pos,
      //轨迹线
        polyline: {
            positions: new Cesium.CallbackProperty(() => {
                return this.linePath;
            }, false),
            show: true,
            arcType: Cesium.ArcType.RHUMB,
            material: Cesium.Color.RED,
            width: 1.5,
            // clampToGround: true, //是否贴地,
            // classificationType: Cesium.ClassificationType.BOTH //也贴模型
        }
    })

  
  }

  // 根据两个坐标点,获取Heading(朝向)
  getHeading = (pointA, pointB) => {
    if(pointA.x === pointB.x && pointA.y === pointB.y) return
    //建立以点A为原点，X轴为east,Y轴为north,Z轴朝上的坐标系
    const transform =  Cesium.Transforms.eastNorthUpToFixedFrame(pointA);
    //向量AB
    const positionvector =  Cesium.Cartesian3.subtract(pointB, pointA, new Cesium.Cartesian3());
    //因transform是将A为原点的eastNorthUp坐标系中的点转换到世界坐标系的矩阵
    //AB为世界坐标中的向量
    //因此将AB向量转换为A原点坐标系中的向量，需乘以transform的逆矩阵。
    const vector =  Cesium.Matrix4.multiplyByPointAsVector(
      Cesium.Matrix4.inverse(transform, new Cesium.Matrix4()),
      positionvector,
      new Cesium.Cartesian3()
    );
    //归一化
    const direction =  Cesium.Cartesian3.normalize(vector, new Cesium.Cartesian3());
    //heading
    const heading = Math.atan2(direction.y, direction.x) - Cesium.Math.PI_OVER_TWO;
    return Cesium.Math.TWO_PI - Cesium.Math.zeroToTwoPi(heading);
  }

  clear = () =>{
    if(this.timer){
      clearInterval(this.timer)
    }
    if (this.Primitive) {
      this.viewer.scene.primitives.remove(this.Primitive)
    }
    
    if (this.entityPath) {
      this.viewer.entities.remove(this.entityPath)
    }

    this.viewer.scene.preUpdate.removeEventListener(this.render)
    this.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
    
    //时间间隔（S）
    this.interval = 2
    this.index = 0 //差值经纬度索引
    this.maxIndex = 0 //最大差值经纬度数组索引
    this.pathIndex = 0//当前经纬度数组索引
    this.forNum = 20 //差值间隔
    this.isLookAt = false //锁定视角
    this.autoDirection = true //自动调整方向
    this.lineNumner = [] //存路线数组
    this.Primitive = null
    this.entityPath = null
    this.hpRoll = new Cesium.HeadingPitchRoll()
    this.linePath = []  //Cesium.Cartesian3
    this.showPath = []  //Cesium.Cartesian
  }
}